Add two numbers¶
Time: O(N); Space: O(1); medium
You are given two non-empty linked lists representing two non-negative integers.
The digits are stored in reverse order and each of their nodes contain a single digit.
Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
Example 1:
Input: l1 = {ListNode} 2->4->3->None, l2 = {ListNode} 5->6->4->None
Output: {ListNode} 7->0->8->None
Explanation:
342 + 465 = 807
Follow up:
What if the the digits in the linked list are stored in non-reversed order?
For example: 3->4->2 + 4->6->5 = 8->0->7
[8]:
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
1. Elementary Math¶
Intuition
Keep track of the carry using a variable and simulate digits-by-digits sum starting from the head of list, which contains the least-significant digit.
Illustration of Adding two numbers
Figure 1. Visualization of the addition of two numbers: 342 + 465 = 807. Each node contains a single digit and the digits are stored in reverse order.
Algorithm
Just like how you would sum two numbers on a piece of paper, we begin by summing the least-significant digits, which is the head of l1 and l2. Since each digit is in the range of 0…9, summing two digits may “overflow”.
For example 5 + 7 = 125 + 7 = 12. In this case, we set the current digit to 22 and bring over the carry = 1 to the next iteration. carry must be either 0 or 1 because the largest possible sum of two digits (including the carry) is 9 + 9 + 1 = 199 + 9 + 1 = 19.
The pseudocode is as following:
Initialize current node to dummy head of the returning list.
Initialize carry to 0.
Initialize p and q to head of l1 and l2 respectively.
Loop through lists l1 and l2 until you reach both ends.
Set x to node p’s value. If p has reached the end of l1, set to 0.
Set y to node q’s value. If q has reached the end of l2, set to 0.
Set sum = x + y + carry.
Update carry = sum // 10.
Create a new node with the digit value of sum % 10 and set it to current node’s next, then advance current node to next.
Advance both p and q.
Check if carry = 1, if so append a new node with digit 11 to the returning list.
Return dummy head’s next node.
Note that we use a dummy head to simplify the code. Without a dummy head, you would have to write extra conditional statements to initialize the head’s value.
Take extra caution of the following cases:
Test case |
Explanation |
---|---|
l1 = [0,1], l2=[0,1,2] |
When one list is longer than the other |
l1=[], l2=[0,1] |
When one list is null, which means an empty list |
l1=[9,9], l2=[1] |
The sum could have an extra carry of one at the end, which is easy to forget |
[9]:
class Solution1(object):
"""
Time: O(N)
Space: O(1)
"""
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
dummy = ListNode(0)
current, carry = dummy, 0
while l1 or l2:
val = carry
if l1:
val += l1.val
l1 = l1.next
if l2:
val += l2.val
l2 = l2.next
carry, val = divmod(val, 10)
current.next = ListNode(val)
current = current.next
if carry == 1:
current.next = ListNode(1)
return dummy.next
[10]:
s = Solution1()
l1 = ListNode(2)
l1.next = ListNode(4)
l1.next.next = ListNode(3)
l2 = ListNode(5)
l2.next = ListNode(6)
l2.next.next = ListNode(4)
res = s.addTwoNumbers(l1, l2)
exp = [7,0,8]
for val in exp:
assert res.val == val
res = res.next
l1 = ListNode(3)
l1.next = ListNode(4)
l1.next.next = ListNode(2)
l2 = ListNode(4)
l2.next = ListNode(6)
l2.next.next = ListNode(5)
res = s.addTwoNumbers(l1, l2)
exp = [7,0,8]
for val in exp:
assert res.val == val
res = res.next
See also:¶
https://leetcode.com/problems/add-two-numbers
https://www.lintcode.com/problem/add-two-numbers/description
Related problems:¶
https://leetcode.com/problems/multiply-strings/
https://leetcode.com/problems/add-binary/
https://leetcode.com/problems/sum-of-two-integers/
https://leetcode.com/problems/add-strings/
https://leetcode.com/problems/add-two-numbers-ii/